﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using System.Web;
using System.IO;
using System.Net;
using System.Configuration;

namespace Web4Comment.SNSAPI.sina
{
   public class SinaSerive:SnsBase,ISerive,ISnsSerive
    {
        ILog logger = LogManager.GetLogger(typeof(SinaSerive));

        public SinaSerive(string app_key, string app_secret, string redirect_uri)
            : base(app_key, app_secret, redirect_uri)
        { this.sns_name = ConfigurationSettings.AppSettings["sina_sns_name"]; }
        public SinaSerive()
            : base()
        { }

        /// <summary>
        /// 根据用户ID获取用户信息
        /// </summary>
        /// <param name="uid">需要查询的用户ID。</param>
        /// <returns></returns>
        public Object Users_Show(long uid)
        {
            var dictionary = new Dictionary<object, object>
            {                
                {"uid",uid}
            };
            return HttpGet<User>("users/show.json", dictionary);
        }

        public String getSnsName()
        {
            return sns_name;
        }
       /// <summary>
       /// 获得在Token中的uid
       /// </summary>
       /// <returns></returns>
        public string getUidByToken()
        {
            AccessToken Token = this.getAccessToken() as AccessToken;

            return Token.uid;
        }

        /// <summary>
        /// OAuth授权之后，获取授权用户的UID
        /// </summary>
        /// <returns></returns>
        public string Account_Get_Uid()
        {
            var dictionary = new Dictionary<object, object>();
            return HttpGet("account/get_uid.json", dictionary);
        }

        public bool isConnect()
        {
            Object Token = this.getAccessToken();

            if (Token == null)
                return false;

            return true;
        }

        #region 获取用户的关注列表
        /// <summary>
        /// 获取用户的关注列表
        /// </summary>
        /// <param name="uid">需要查询的用户UID。</param>
        /// <param name="count">单页返回的记录条数，默认为50，最大不超过200。</param>
        /// <param name="cursor">返回结果的游标，下一页用返回值里的next_cursor，上一页用previous_cursor，默认为0。</param>
        /// <returns></returns>
        public Object Friendships_Friends(long uid, int? count, int? cursor)
        {
            var dictionary = new Dictionary<object, object>
            {                
                {"uid",uid},
                {"count",count??50},
                {"cursor",cursor??0}
            };
            return HttpGet<Users>("friendships/friends.json", dictionary);
        }
        #endregion

        /// <summary>
        /// 获取Authorization Code。
        /// </summary>
        public void GetAuthorizationCode()
        {
            string url = string.Format("{0}?client_id={1}&response_type=code&redirect_uri={2}", authorizeUrl, this.App_Key, this.Redirect_Uri);

            HttpContext.Current.Response.Redirect(url);
        }

        /// <summary>
        /// 使用Authentication Code获取Access Token。
        /// </summary>
        /// <param name="code">获得的Authorization Code。</param>
        public string GetAccessTokenByAuthorizationCode(string code)
        {
            string queryString = string.Format("grant_type=authorization_code&code={0}&client_id={1}&client_secret={2}&redirect_uri={3}", code, this.App_Key, this.App_Secret, this.Redirect_Uri);

            AccessToken Token = AccessTokenRequest(queryString);

            HttpContext.Current.Session.Add("sina_access_token", Token);

            return Token.uid;
        }

        public Object getAccessToken()
        {
            return HttpContext.Current.Session["sina_access_token"];
        }

        /// <summary>
        /// 转换json→AccessToken实例
        /// </summary>
        /// <param name="queryString">获取授权过的Access Token返回值</param>
        /// <returns></returns>
        private AccessToken AccessTokenRequest(string queryString)
        {
            var jsonResult = string.Empty;
            try
            {
                
                jsonResult = this.HttpMethod.HttpPost(tokenUrl, queryString);

            }
            catch (WebException e)
            {
                if (e.Status == WebExceptionStatus.ProtocolError)
                {
                    StreamReader reader = new StreamReader(e.Response.GetResponseStream(), Encoding.UTF8);
                    jsonResult = reader.ReadToEnd();
                }
            }

            if (jsonResult.Contains("error"))
            {
                throw new WebException();
            }
            
            return jsonResult.ToEntity<AccessToken>();
        }



        #region Must
        #region Post
        public T HttpPost<T>(string partUrl, IDictionary<object, object> dictionary) where T : class
        {
            return HttpPost<T>(partUrl, dictionary, null);
        }

        public T HttpPost<T>(string partUrl, IDictionary<object, object> dictionary, byte[] file) where T : class
        {
            AccessToken Token = this.getAccessToken() as AccessToken;

            dictionary.Add("access_token", Token.access_token);

            var url = base.baseUrl.ToFormat(partUrl);
            var query = dictionary.ToQueryString();
            logger.Error(url);
            logger.Error(query);
            var json = string.Empty;
            if (file != null)
            {
                json = base.HttpMethod.HttpPost(url, dictionary, file);
            }
            else
            {
                json = base.HttpMethod.HttpPost(url, query);
            }

            return json.ToEntity<T>();
        }

        public string HttpPost(string partUrl, IDictionary<object, object> dictionary)
        {
            AccessToken Token = this.getAccessToken() as AccessToken;

            dictionary.Add("access_token", Token.access_token);

            var url = base.baseUrl.ToFormat(partUrl);
            var query = dictionary.ToQueryString();
            logger.Error(url);
            logger.Error(query);
            return base.HttpMethod.HttpPost(url, query);
        }
        #endregion

        #region Get
        public T HttpGet<T>(string partUrl, IDictionary<object, object> dictionary) where T : class
        {
            AccessToken Token = this.getAccessToken() as AccessToken;

            dictionary.Add("access_token", Token.access_token);

            var url = base.baseUrl.ToFormat(partUrl);
            var query = dictionary.ToQueryString();
            logger.Error(url + "?" + query);
            var json = base.HttpMethod.HttpGet(url + "?" + query);
            return json.ToEntity<T>("json");
        }

        public string HttpGet(string partUrl, IDictionary<object, object> dictionary)
        {
            AccessToken Token = this.getAccessToken() as AccessToken;

            dictionary.Add("access_token", Token.access_token);

            var url = base.baseUrl.ToFormat(partUrl);
            var query = dictionary.ToQueryString();
            logger.Error(url + "?" + query);
            return base.HttpMethod.HttpGet(url + "?" + query);
        }
        #endregion
        #endregion
    }
}
